package com.evil.application.strategy.reporting;

import cn.hutool.core.collection.CollectionUtil;
import co.elastic.clients.elasticsearch._types.aggregations.Aggregate;
import com.alibaba.fastjson.JSON;
import com.evil.application.enums.reporting.ReportingTypeEnum;
import com.evil.application.pojo.dto.reporting.AggBaseDTO;
import com.evil.application.pojo.dto.reporting.ApplicationReportingDTO;
import com.evil.application.pojo.dto.reporting.data.ReportingDataRespDTO;
import com.evil.application.pojo.dto.reporting.data.ReportingTreeDataDTO;
import com.evil.common.es.dto.AggTreeParam;
import com.evil.common.es.dto.AggTreeResult;
import com.evil.common.es.util.ElasticsearchUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 报表类型-树状表
 *
 * @author liyang
 * @date 2022-08-08 00:00
 */
@Slf4j
@Service
@AllArgsConstructor
public class ReportingDataTreeTableImpl implements ReportingData {

    @Override
    public ReportingTypeEnum type() {
        return ReportingTypeEnum.TREE_TABLE;
    }

    /**
     * 统计
     *
     * @param reportingDTO reportingDTO
     * @param aggregations aggregations
     * @return ReportingDataRespDTO
     */
    @Override
    public ReportingDataRespDTO calculation(ApplicationReportingDTO reportingDTO, Aggregate aggregations) {
        ReportingDataRespDTO reportingDataRespDTO = new ReportingDataRespDTO(reportingDTO.getReportingKey());
        if (null == aggregations) {
            return reportingDataRespDTO;
        }
        // 聚合树信息
        AggTreeParam<AggBaseDTO> param = this.analysisAggTreeParam(reportingDTO);

        // aggTree
        List<AggTreeResult> aggTree = ElasticsearchUtil.analysis(null, param, aggregations);
        log.info("reportData|chart|key:{}|aggTree:{}", reportingDTO.getReportingKey(), JSON.toJSONString(aggTree));

        if (CollectionUtil.isEmpty(aggTree)) {
            return reportingDataRespDTO;
        }

        reportingDataRespDTO.setTreeValues(this.recursion(aggTree));
        return reportingDataRespDTO;
    }

    private List<ReportingTreeDataDTO> recursion(List<AggTreeResult> aggTree) {
        List<ReportingTreeDataDTO> treeValues = new ArrayList<>();
        aggTree.forEach(e -> {
            ReportingTreeDataDTO tree = new ReportingTreeDataDTO(e.getTitle(), String.valueOf(e.getValue()));
            tree.setChildren(this.recursion(e.getChildren()));
            treeValues.add(tree);
        });
        return treeValues;
    }
}
